package com.ymttest.common.order.userquery;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.shop2cn.iapi.sqsynctrade.paremeter.mongo.details.Delivery;
import com.shop2cn.iapi.sqsynctrade.paremeter.mongo.details.Fund;
import com.shop2cn.iapi.sqsynctrade.paremeter.mongo.details.Product;
import com.shop2cn.iapi.sqsynctrade.paremeter.mongo.details.Refund;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.StockStatusEnum;
import com.ymatou.iapi.sellerquery.parameter.enums.SalesRefundStatusEnum;
import com.ymatou.iapi.synctrade.parameter.mongo.Order;
import com.ymatou.query.trading.api.parameter.ProductPromotion;
import com.ymttest.common.entitie.OrderItemInfo;
import com.ymttest.common.entitie.OrderItemInfoExt;
import com.ymttest.common.enums.SalesTypeStringEnum;
import com.ymttest.common.order.userquery.client.ProductClient;
import com.ymttest.common.order.userquery.client.SellerInfoClient;
import com.ymttest.common.order.userquery.model.vo.SingleOrderInfo;
import com.ymttest.common.order.userquery.model.vo.StatusLogInfo;
import com.ymttest.common.order.userquery.util.OrderHelper;
import com.ymttest.common.order.userquery.util.Utils;

public class SingleOrderInfoBuilder {

	public static SingleOrderInfo convertOrder(Order order,
			ProductClient productClient, SellerInfoClient sellerInfoClient) {

		SingleOrderInfo orderInfo = new SingleOrderInfo();
		orderInfo.setOrderId(order.getId());
		orderInfo.setUserId(order.getUserId());
		orderInfo.setBuyerId(order.getSellerId());
		orderInfo.setAddTime(order.getAddTime());
		orderInfo.setAcceptTime(order.getAcceptTime());
		orderInfo.setTradingStatus(order.getTradingStatus());
		orderInfo
				.setRiskVerifiedStatus(Utils.zeroIfNull(order.getRiskStatus()));
		orderInfo.setPaidInFull(true); // 没有补款，默认值true
		orderInfo.setShangouOrder(false);
		orderInfo.setBuyerLoginId(order.getUserLogin());
		orderInfo.setSellerLoginId(order.getSellerLogin());
		orderInfo.setBuyerNickName(order.getUserLogin());
		orderInfo.setDispathTime(order.getDeliveryTime());
		orderInfo.setShippedByXlobo(order.isXlobo());
		orderInfo.setSalesRefundStatus(OrderHelper.getSalesRefundStatus(order
				.getRefunds()));
		orderInfo.setCancelReason(order.getReason());
		orderInfo.setMainOrderId(order.getMainOrderId());
		orderInfo.setYmtCouponAmount(order.getYmtCouponAmount());
		orderInfo.setYmtCouponCode(order.getYmtCouponCode());
		orderInfo.setSellerCouponAmount(Utils.zeroIfNull(order
				.getSellerCouponAmount()));
		orderInfo.setSellerCouponCode(order.getSellerCouponCode());
		orderInfo.setPayableAmount(order.getPayableAmount());
		orderInfo.setRealSettlementAmountOfCoupon(order.getFund()
				.getRefundCoupon());
		orderInfo.setYmtPromotionAmount(Utils.zeroIfNull(order
				.getYmtPromotionAmount()));
		orderInfo.setPromotionReducedAmount(Utils.zeroIfNull(order
				.getSellerPromotionAmount()));

		if (null != order.getDelivery()) {
			orderInfo.setBusynessTypeList(order.getDelivery().getBizType());
		}

		orderInfo.setOrderPrice(order.getTotalPrice());
		orderInfo.setOrderDiscount(order.getPreDiscount());
		orderInfo.setFreight(order.getFreight());
		orderInfo.setDiscount(order.getPreDiscount());
		orderInfo.setTotalPrice(order.getTotalPrice());
		orderInfo.setNeedPrePayAmountOfCash(OrderHelper
				.getNeedPrePayAmountOfCash(order));
		orderInfo.setTotalSalesRefundAmount(order.getRefunds() != null ? order
				.getRefunds()
				.stream()
				.filter(e -> e.getRefundStatus().equals(
						SalesRefundStatusEnum.Success.getCode()))
				.map(e -> Utils.zeroIfNull(e.getRefundAmount()))
				.reduce(BigDecimal::add).orElse(BigDecimal.ZERO)
				: BigDecimal.ZERO);
		orderInfo.setAddress(com.ymatou.iapi.optrade.parameter.utill.Utils.decryptAES(order.getUaddress()));
		orderInfo.setPostCode(order.getPostCode());
		orderInfo.setReceivePerson(order.getReceiver());
		orderInfo.setPhone(com.ymatou.iapi.optrade.parameter.utill.Utils.decryptAES(order.getUphone()));
		orderInfo.setTelephone(com.ymatou.iapi.optrade.parameter.utill.Utils.decryptAES(order.getUphone()));
		orderInfo.setEmail(order.getEmail());
		orderInfo.setLeaveWord(order.getComment());
		orderInfo.setCouponCode(order.getYmtCouponCode());
		orderInfo.setCouponValue(order.getYmtCouponAmount() != null ? order
				.getYmtCouponAmount() : BigDecimal.ZERO);
		orderInfo.setSellerCouponCode(order.getSellerCouponCode());
		orderInfo
				.setSellerCouponAmount(order.getSellerCouponAmount() != null ? order
						.getSellerCouponAmount() : BigDecimal.ZERO);
		orderInfo.setPaidTime(order.getPaidTime());
		orderInfo.setApplyPostPayTime(null);
		orderInfo.setPostPaidTime(null);
		orderInfo.setConfirmedTime(order.getReceiveTime());
		orderInfo.setCancelTime(order.getCancelTime());
		orderInfo.setDispatchTime(order.getDeliveryTime());
		orderInfo.setAutoCancelOrderHours(order.getAutoCancelHour());
		orderInfo.setPreSaleOrder(order.isPreSale());
		orderInfo.setTradingId(order.getTradingId() != null
				&& order.getTradingId() > 0 ? order.getTradingId() : order
				.getMainOrderId());
		orderInfo.setSellerAgent(order.isSellerAgent());
		orderInfo.setOptimumSeller(order.isOptimumSeller());

		// YMT_OrderInfo => Order.Product
		List<Product> products = order.getProducts();
		boolean isExistProductInfo = !CollectionUtils.isEmpty(products);
		int logisticsType = isExistProductInfo ? Utils.zeroIfNull(products.get(
				0).getDeliveryType()) : LogisticsTypeEnum.Unknown.getCode();
		int stockStatus = isExistProductInfo ? Utils.zeroIfNull(products.get(0)
				.getStockStatus()) : StockStatusEnum.Spot.getCode();
		boolean packageDelivery = isExistProductInfo ? (products.get(0)
				.getDeliveryType() == LogisticsTypeEnum.PackageDelivery
				.getCode() ? order.isLocalDelivery() : false) : false;
		orderInfo.setLogisticsType(logisticsType);
		orderInfo.setStockStatus(stockStatus);
		orderInfo.setPackageDelivery_DomesticDelivered(packageDelivery);
		orderInfo.setOrderItemList(convertProduct(products, order,
				productClient, sellerInfoClient)); // 商品信息

		// YMT_OrderExt => Order
		orderInfo.setPlatformEnum(OrderHelper.getPlatformEnumInfo(
				order.getPlatSource()).getValue());
		orderInfo.setNeedUploadIdCard(order.isNeedUploadIdCard());
		orderInfo.setHaveUploadedIdCard(order.isUploadedIdCard());
		orderInfo.setIsNewSellerOrder(order.isNewSeller());
		orderInfo.setIsNewCustomerOrder(order.isNewUser());
		orderInfo.setIsFirstOrder(order.isNewUser());

		// Ymt_O_OrderNote => Order
		orderInfo.setSellerNote(order.getContent() == null ? "" : order.getContent());
		orderInfo.setRemarkLevel(order.getRemarkLevel());

		// Ymt_OrderState => Order.Fund; Ymt_RefundBill => Order.Refunds
		convertFund(orderInfo, order);

		// Ymt_Order_Frozen => Order.Delivery
		Delivery delivery = order.getDelivery();
		if (delivery != null) {
			orderInfo.setBillCodeList(delivery.getBillCode());
			orderInfo.setDelayReceiveFrozenTime(delivery.getFrozenTime());
			orderInfo.setDelayReceiveUpdateTime(delivery.getUpdateTime());
			orderInfo
					.setDelayReceiveUserId(delivery.getDelayUserId() != null ? delivery
							.getDelayUserId() : order.getSellerId());
			Date autoReceiveTime = !delivery.isPause()
					&& delivery.getFrozenTime() != null ? delivery
					.getFrozenTime() : null;
			orderInfo.setAutoReceiveEnabled(autoReceiveTime != null);
			orderInfo.setAutoReceiveTime(autoReceiveTime);
		} else {
			orderInfo.setDelayReceiveUserId(order.getSellerId());
		}

		orderInfo.setCredited(false);
		orderInfo.setTotalPriceChange(Utils.zeroIfNull(order.getPreDiscount())
				.add(Utils.zeroIfNull(BigDecimal.ZERO)));

		// OrderSummary 不需要

		orderInfo.setDeleted(order.isDeleted());
		orderInfo.setStatusLogList(convertStatusLog(order));

		// 分销订单信息
		orderInfo.setHunterId(order.getHunterId());
		orderInfo.setHunterOrderType(order.getHunterOrderType());

		return orderInfo;
	}

	private static List<StatusLogInfo> convertStatusLog(Order order) {
		List<StatusLogInfo> statusLogInfos = new ArrayList<>();
		if (order.getStatusLog() == null || order.getStatusLog().size() <= 0) {
			return statusLogInfos;
		}
		order.getStatusLog().forEach(statusLog -> {
			StatusLogInfo statusLogInfo = new StatusLogInfo();
			statusLogInfo.setLogStatus(statusLog.getLogStatus());
			statusLogInfo.setLogTime(statusLog.getLogTime());
			statusLogInfo.setMemo(statusLog.getMemo());
			statusLogInfos.add(statusLogInfo);
		});
		return statusLogInfos;
	}

	private static void convertFund(SingleOrderInfo orderInfo, Order order) {
		Fund fund = order.getFund();
		orderInfo.setPostPaidAmountOfCoupon(BigDecimal.ZERO);
		orderInfo.setPostPaidAmountOfGift(fund.getPostGif());
		orderInfo.setPaidAmountOfFreeCard(fund.getPaidFreeCard());
		orderInfo.setPaidAmountOfCoupon(BigDecimal.ZERO); // 废弃字段
		orderInfo.setPaidAmountOfYmtCoupon(fund.getYmtCoupon());
		orderInfo.setPaidAmountOfCash(fund.getPaidCash()
				.add(fund.getPostCash()));

		orderInfo.setFirstPay(OrderHelper.getPrePaidAmount(order));
		orderInfo.setRefund(OrderHelper.getRefundedAmount(fund));
		orderInfo.setRealPay(OrderHelper.getTotalPayAmount(order).subtract(
				orderInfo.getRefund()));
		orderInfo.setRealPostPay(OrderHelper.getPostPaidAmount(fund));
		orderInfo.setRealPaidAmountOfCash(OrderHelper
				.getCashAmountOfRealPay(fund));
		orderInfo.setRealPaidAmountOfGift(OrderHelper
				.getGiftAmountOfRealPay(fund));
		orderInfo
				.setDiscountOfThirdParty(Utils.zeroIfNull(fund.getDiscount3P()));
		orderInfo.setTotalRefundThirdPartyDiscount(Utils.zeroIfNull(fund
				.getRefundDiscount3P()));
		orderInfo.setMaxCanRefundAmount(fund.getPaidCash().add(
				Utils.zeroIfNull(fund.getDiscount3P())));
	}
	
	private static List<OrderItemInfo> convertProduct(List<Product> products, Order order, ProductClient productClient, SellerInfoClient sellerInfoClient) {
        List<OrderItemInfo> orderItemInfos = new ArrayList<>();
        List<Refund> refunds = order.getRefunds();

        if (!CollectionUtils.isEmpty(products)) {
            HashMap<String, String> mapProductCountry = Maps.newHashMap();
            HashMap<String, String> mapCountryFlag = Maps.newHashMap();
            if (products.get(0).getDeliveryType() == LogisticsTypeEnum.China.getCode()) {
                HashMap<String, String> mapProductIdVersion = Maps.newHashMap();
                products.forEach(p -> mapProductIdVersion.put(p.getProductId(), p.getProductVersion()));

                mapProductCountry = productClient.getProductCountry(mapProductIdVersion);
                if (mapProductCountry.size() > 0) {
                    HashSet<String> set = new HashSet<>();
                    set.addAll(mapProductCountry.values());
                    mapCountryFlag = sellerInfoClient.getCountryInfos(Lists.newArrayList(set));
                }
            }


            for (Product product : products) {
                OrderItemInfo itemInfo = new OrderItemInfo();
                //原产地国家和国旗地址
                if (product.getDeliveryType() == LogisticsTypeEnum.China.getCode()) {
                    String country = mapProductCountry.get(product.getProductId());
                    if (!Strings.isNullOrEmpty(country)) {
                        itemInfo.setCountryOfOrigin(country);
                        String flagUrl = mapCountryFlag.get(country);
                        if (!Strings.isNullOrEmpty(flagUrl)) {
                            itemInfo.setCountryFlagUrl(flagUrl);
                        }
                    }
                }

                OrderItemInfoExt itemInfoExt = null;
                if (product.getActId() != null && product.getActId() > 0) {
                    itemInfoExt = new OrderItemInfoExt();
                    itemInfoExt.setActivityId(Utils.zeroIfNull(product.getActId()));
                    itemInfoExt.setActivityTemplateId(Utils.zeroIfNull(product.getActTemplateId()));
                }
                itemInfo.setOrderItemInfoExt(itemInfoExt);

                itemInfo.setSailProtected(Utils.zeroIfNull(product.getDeliveryType()) == 3);
                itemInfo.setPrice(product.getPrdPrePrice());
                itemInfo.setPropertyInfo(product.getPropertyInfo());
                itemInfo.setAmount(Utils.zeroIfNull(product.getPrdCount()));
                itemInfo.setCatalogId(product.getCataId());
                itemInfo.setSku(product.getSku());
                itemInfo.setProductId(product.getProductId());
                itemInfo.setOrderItemId(product.getItemId());
                itemInfo.setPictureUrl(product.getPicUrl());
                itemInfo.setTitle(product.getTitle());
                itemInfo.setFirstCategoryId(product.getCata1Id());
                itemInfo.setSubProductCategoryId(product.getCata2Id());
                itemInfo.setThirdCategoryId(product.getCata3Id());
                itemInfo.setLogisticsType(Utils.zeroIfNull(product.getDeliveryType()));
                itemInfo.setStockStatus(Utils.zeroIfNull(product.getStockStatus()));
                itemInfo.setBondedArea(Utils.zeroIfNull(product.getBondedArea()));
                itemInfo.setPriceType(Utils.zeroIfNull(product.getPriceType()));
                itemInfo.setProductRefundChannel(Utils.zeroIfNull(product.getRefundChannel()));
                itemInfo.setFreightFree(product.isFreightFree());
                itemInfo.setSellerCouponAmount(Utils.zeroIfNull(product.getPrdSellerCoupon()));
                itemInfo.setYmtCouponAmount(Utils.zeroIfNull(product.getPrdYmtCoupon()));
                itemInfo.setProductOriginalPrice(Utils.zeroIfNull(product.getPrdOriginalPrice()));
                itemInfo.setProductPrice(Utils.zeroIfNull(product.getPrdPrice()));
                itemInfo.setDiscount(product.getPrdDiscount());
                itemInfo.setRefundBillNo(product.getPrdRefundNo());
                itemInfo.setTariffType(Utils.zeroIfNull(product.getTariffType()));
                itemInfo.setSalesType(SalesTypeStringEnum.findByCodeToString(product.getSalesType()));
                itemInfo.setSupportRtnWithoutReason(product.getReturn7d());
                itemInfo.setPremium(BigDecimal.ZERO);
                itemInfo.setPreSale(order.isPreSale());
                itemInfo.setThirdPartyDiscount(Utils.zeroIfNull(product.getPrdDiscount3P()));
                itemInfo.setProductVer(product.getProductVersion());
                itemInfo.setPspProduct(product.isPspProduct());
                itemInfo.setYmtPromotionAmount(Utils.zeroIfNull(product.getPrdYmtPromotionAmount()));
                itemInfo.setFreight(product.getPrdFreight());

                BigDecimal maxCanRefundProAmount = product.getPrdPrice().multiply(new BigDecimal(product.getPrdCount()))
                        .add(product.getPrdDiscount())
                        .subtract(product.getPrdYmtCoupon())
                        .subtract(product.getPrdSellerCoupon())
                        .subtract(product.getPrdPromotionAmount())
                        .subtract(Utils.zeroIfNull(product.getPrdYmtPromotionAmount()));
                itemInfo.setMaxCanRefundProAmount(maxCanRefundProAmount);

                if (product.getPromotionId() != null && product.getPromotionId() > 0) {
                    ProductPromotion productPromotion = new ProductPromotion();
                    productPromotion.setCondition(product.getPromotionCondition());
                    productPromotion.setID((product.getPromotionId().intValue()));
                    productPromotion.setName(product.getPromotionName());
                    productPromotion.setReducedAmount(product.getPromotionAmount());
                    productPromotion.setType(product.getPromotionType());
                    productPromotion.setContent(product.getPromotionContent());
                    productPromotion.setPartialReducedAmount(product.getPrdPromotionAmount());
                    itemInfo.setPromotion(productPromotion);
                }

                if (!CollectionUtils.isEmpty(refunds)) {
                    for (Refund refund : refunds) {
                        //找到商品上匹配退款单号且退款成功或申请中的退款单
                        if (!Strings.isNullOrEmpty(itemInfo.getRefundBillNo()) && !Strings.isNullOrEmpty(refund.getRefundNo())
                                && itemInfo.getRefundBillNo().equals(refund.getRefundNo())
                                && refund.getRefundStatus() != null) {
                            itemInfo.setRefundStatus(refund.getRefundStatus());
                            if (!refund.getRefundStatus().equals(SalesRefundStatusEnum.Fail.getCode())) {
                                itemInfo.setRefundFreight(Utils.zeroIfNull(refund.getRefundAmountFreight()));
                            }
                            break;
                        }
                    }
                }
                orderItemInfos.add(itemInfo);
            }

        }
        return orderItemInfos;
    }
}
